#include "app_config.h"

/*********************************************************
2022.6.10
未完成的功能
1.充电
2.低电量指示
3.离机提示


完成的功能
1.EMS驱动
2.按键开关机，按键调节强度
3.放电的处理

充电的流程整个充电过程的状态机这这里了
(app_charge_event_handler)

1.charge_ldo5v_in_deal 接入了5V
2.charge_start_deal  开始充电

[00:13:21.782][Info]: [APP_CHARGE]charge_ldo5v_in_deal
[00:13:21.783][Info]: [APP_CHARGE]charge_start_deal

[00:13:27.976][Info]: [APP_CHARGE]charge_ldo5v_off_deal
[00:13:27.977][Info]: [APP_CHARGE]charge_close_deal

************************************************************/

#ifdef CONFIG_BOARD_AC6323A_DEMO

#include "system/includes.h"
#include "device/key_driver.h"
#include "asm/mcpwm.h"
#include "asm/chargestore.h"
#include "asm/charge.h"
#include "rtc_alarm.h"
#include "asm/pwm_led.h"
#include "asm/power/p33.h"
#include "user_cfg.h"
#include "usb/otg.h"
#include "norflash.h"
#include "device/vm.h"
#include "EMS_TO_TEMS_DRIVE.h"
#include "syscfg_id.h"

#define LOG_TAG_CONST       BOARD
#define LOG_TAG             "[BOARD]"
#define LOG_ERROR_ENABLE
#define LOG_DEBUG_ENABLE
#define LOG_INFO_ENABLE
/* #define LOG_DUMP_ENABLE */
#define LOG_CLI_ENABLE
#include "debug.h"

u16 VBAT_V;//判断电量低使用的
u8 VBAT_CD_Full_Delay20S=0;//充满电20秒后自动关机进入低功耗
u8 LED_SHOW_TIMER_DATA=15;//控制15分钟倒计时
u8 LED_SHOW_TIMER_DELAY_500MS=0;//控制关机倒计时使用的

//清楚BT2.4G遥控接收数据使用的
u8 BT24G_Clear_Delays=0;
u8 rx_bufferLS[4];
u16 LED_Delay_500S=0;
u16 EMS_LJ_Delay_120S=0,KEY_ADD_Delay1=0;//判断离机2分钟后自动关机
u8 KEY_ADD_Delay2=0,KEY_ADD_Delay3=0;//独立的强度加按键的判断延时使用的

void LED_8data_Show_2ms(void *priv);
void SYS_to_LED_OFF_Init(void);
void SYS_to_LED_ON_Init(void);

u8 SYS_Init_OK_Flag=0;//系统正常开机初始化成功
u8 LED_Sao_Ci=0;//扫描LED数码管使用的
u8 LED_Show_Ci=0;
const u8 LED_CD_DataX[]={0x01,0x03,0x07,0x27,0x37,0x3F,0x78};//流动1到6，充满显示F

u8 LED_8_Data=0;//8字数码管的显示值
const u8 LED_8_DataX[]={0x3f,0x03,0x6D,0x4F,0x53,0x5E,0x7E,0x0B,0x7F,0x5F};
u16 LED_2ms_ID=0,SYS_ON_TO_OFF_15Ms_ID=0;

u8 SYS_Flag=0;//0关机，1开机，2离机放电，3低电量，4充电中，5充满电
u16 PWM_IN_CI=0;//实际脉冲个数
u8 Power_PWM_Ture=0;//控制是否开启升压结束判断的
u8 PWM_ON_Ture=0;//脉冲开始初始化使用的
u8 PWM_Type=0;//控制波形类型使用的0到5，总共6个模式，0为模式2，3,4的循环
u8 PWM_Type_NOW=0;//当前的模式
u8 PWM_Type0_Delay500ms=0;//模式0时需要每隔1分钟切换一次
u8  QD_KEY_Data_Type=0;//按键按的强度等级0-9
extern u8 SYS_24G_SN_BYTE[4];//控制遥控器配对的密码使用的预留4个字节;

void board_power_init(void);

/************************** LOW POWER config ****************************/
const struct low_power_param power_param = {
    .config         = TCFG_LOWPOWER_LOWPOWER_SEL,          //0：sniff时芯片不进入低功耗  1：sniff时芯片进入powerdown
    .btosc_hz       = TCFG_CLOCK_OSC_HZ,                   //外接晶振频率
    .delay_us       = TCFG_CLOCK_SYS_HZ / 1000000L,        //提供给低功耗模块的延时(不需要需修改)
    .btosc_disable  = TCFG_LOWPOWER_BTOSC_DISABLE,         //进入低功耗时BTOSC是否保持
    .vddiom_lev     = TCFG_LOWPOWER_VDDIOM_LEVEL,          //强VDDIO等级,可选：2.0V  2.2V  2.4V  2.6V  2.8V  3.0V  3.2V  3.6V
    .vddiow_lev     = TCFG_LOWPOWER_VDDIOW_LEVEL,          //弱VDDIO等级,可选：2.1V  2.4V  2.8V  3.2V
    .osc_type       = TCFG_LOWPOWER_OSC_TYPE,
    .lpctmu_en 		= TCFG_LP_TOUCH_KEY_ENABLE,
    .vd13_cap_en    = TCFG_VD13_CAP_EN,
};

/************************** KEY MSG****************************/
/*各个按键的消息设置，如果USER_CFG中设置了USE_CONFIG_KEY_SETTING为1，则会从配置文件读取对应的配置来填充改结构体*/
/* u8 key_table[KEY_NUM_MAX][KEY_EVENT_MAX] = { */
// SHORT           LONG              HOLD              UP              DOUBLE           TRIPLE
/* }; */


// *INDENT-OFF*
/************************** UART config****************************/
#if TCFG_UART0_ENABLE
UART0_PLATFORM_DATA_BEGIN(uart0_data)
    .tx_pin = TCFG_UART0_TX_PORT,                             //串口打印TX引脚选择
    .rx_pin = TCFG_UART0_RX_PORT,                             //串口打印RX引脚选择
    .baudrate = TCFG_UART0_BAUDRATE,                          //串口波特率

    .flags = UART_DEBUG,                                      //串口用来打印需要把改参数设置为UART_DEBUG
UART0_PLATFORM_DATA_END()
#endif //TCFG_UART0_ENABLE


/************************** CHARGE config****************************/
#if TCFG_CHARGE_ENABLE
CHARGE_PLATFORM_DATA_BEGIN(charge_data)
    .charge_en              = TCFG_CHARGE_ENABLE,              //内置充电使能
    .charge_poweron_en      = TCFG_CHARGE_POWERON_ENABLE,      //是否支持充电开机
    .charge_full_V          = TCFG_CHARGE_FULL_V,              //充电截止电压
    .charge_full_mA			= TCFG_CHARGE_FULL_MA,             //充电截止电流
    .charge_mA				= TCFG_CHARGE_MA,                  //充电电流
/*ldo5v拔出过滤值，过滤时间 = (filter*2 + 20)ms,ldoin<0.6V且时间大于过滤时间才认为拔出
 对于充满直接从5V掉到0V的充电仓，该值必须设置成0，对于充满由5V先掉到0V之后再升压到xV的
 充电仓，需要根据实际情况设置该值大小*/
	.ldo5v_off_filter		= 100,
    .ldo5v_on_filter        = 50,
    .ldo5v_keep_filter      = 220,
    .ldo5v_pulldown_lvl     = CHARGE_PULLDOWN_200K,            //下拉电阻档位选择
    .ldo5v_pulldown_keep    = 1,
//1、对于自动升压充电舱,若充电舱需要更大的负载才能检测到插入时，请将该变量置1,并且根据需求配置下拉电阻档位
//2、对于按键升压,并且是通过上拉电阻去提供维持电压的舱,请将该变量设置1,并且根据舱的上拉配置下拉需要的电阻挡位
//3、对于常5V的舱,可将改变量设为0,省功耗
//4、为LDOIN防止被误触发唤醒,可设置为200k下拉
	.ldo5v_pulldown_en		= 1,
CHARGE_PLATFORM_DATA_END()
#endif//TCFG_CHARGE_ENABLE

    /************************** AD KEY ****************************/
#if TCFG_ADKEY_ENABLE
const struct adkey_platform_data adkey_data = {
    .enable = TCFG_ADKEY_ENABLE,                              //AD按键使能
    .adkey_pin = TCFG_ADKEY_PORT,                             //AD按键对应引脚
    .ad_channel = TCFG_ADKEY_AD_CHANNEL,                      //AD通道值
    .extern_up_en = TCFG_ADKEY_EXTERN_UP_ENABLE,              //是否使用外接上拉电阻
    .ad_value = {                                             //根据电阻算出来的电压值
        TCFG_ADKEY_VOLTAGE0,
        TCFG_ADKEY_VOLTAGE1,
        TCFG_ADKEY_VOLTAGE2,
        TCFG_ADKEY_VOLTAGE3,
        TCFG_ADKEY_VOLTAGE4,
        TCFG_ADKEY_VOLTAGE5,
        TCFG_ADKEY_VOLTAGE6,
        TCFG_ADKEY_VOLTAGE7,
        TCFG_ADKEY_VOLTAGE8,
        TCFG_ADKEY_VOLTAGE9,
    },
    .key_value = {                                             //AD按键各个按键的键值
        TCFG_ADKEY_VALUE0,
        TCFG_ADKEY_VALUE1,
        TCFG_ADKEY_VALUE2,
        TCFG_ADKEY_VALUE3,
        TCFG_ADKEY_VALUE4,
        TCFG_ADKEY_VALUE5,
        TCFG_ADKEY_VALUE6,
        TCFG_ADKEY_VALUE7,
        TCFG_ADKEY_VALUE8,
        TCFG_ADKEY_VALUE9,
    },
};
#endif

/************************** IO KEY ****************************/
#if TCFG_IOKEY_ENABLE
const struct iokey_port iokey_list[] = {
	{
		.connect_way = TCFG_IOKEY_POWER_CONNECT_WAY,          //IO按键的连接方式
		.key_type.one_io.port = TCFG_IOKEY_POWER_ONE_PORT,    //IO按键对应的引脚
		.key_value = 0,                                       //按键值
	},

	{
		.connect_way = TCFG_IOKEY_PREV_CONNECT_WAY,
		.key_type.one_io.port = TCFG_IOKEY_PREV_ONE_PORT,
		.key_value = 1,
	},

	{
		.connect_way = TCFG_IOKEY_NEXT_CONNECT_WAY,
		.key_type.one_io.port = TCFG_IOKEY_NEXT_ONE_PORT,
		.key_value = 2,
	},
};
const struct iokey_platform_data iokey_data = {
	.enable = TCFG_IOKEY_ENABLE,                              //是否使能IO按键
	.num = ARRAY_SIZE(iokey_list),                            //IO按键的个数
	.port = iokey_list,                                       //IO按键参数表
};

#if MULT_KEY_ENABLE
//组合按键消息映射表
//配置注意事项:单个按键按键值需要按照顺序编号,如power:0, prev:1, next:2
//bit_value = BIT(0) | BIT(1) 指按键值为0和按键值为1的两个按键被同时按下,
//remap_value = 3指当这两个按键被同时按下后重新映射的按键值;
const struct key_remap iokey_remap_table[] = {
	{.bit_value = BIT(0) | BIT(1), .remap_value = 3},
	{.bit_value = BIT(0) | BIT(2), .remap_value = 4},
	{.bit_value = BIT(1) | BIT(2), .remap_value = 5},
};

const struct key_remap_data iokey_remap_data = {
	.remap_num = ARRAY_SIZE(iokey_remap_table),
	.table = iokey_remap_table,
};
#endif

#endif

#if TCFG_RTC_ALARM_ENABLE
const struct sys_time def_sys_time = {  //初始一下当前时间
    .year = 2020,
    .month = 1,
    .day = 1,
    .hour = 0,
    .min = 0,
    .sec = 0,
};
const struct sys_time def_alarm = {     //初始一下目标时间，即闹钟时间
    .year = 2050,
    .month = 1,
    .day = 1,
    .hour = 0,
    .min = 0,
    .sec = 0,
};

extern void alarm_isr_user_cbfun(u8 index);
RTC_DEV_PLATFORM_DATA_BEGIN(rtc_data)
    .default_sys_time = &def_sys_time,
    .default_alarm = &def_alarm,
    /* .cbfun = NULL,                      //闹钟中断的回调函数,用户自行定义 */
    .cbfun = alarm_isr_user_cbfun,
RTC_DEV_PLATFORM_DATA_END()
#endif

/************************** PWM_LED ****************************/
#if TCFG_PWMLED_ENABLE
LED_PLATFORM_DATA_BEGIN(pwm_led_data)
	.io_mode = TCFG_PWMLED_IOMODE,              //推灯模式设置:支持单个IO推两个灯和两个IO推两个灯
	.io_cfg.one_io.pin = TCFG_PWMLED_PIN,       //单个IO推两个灯的IO口配置
LED_PLATFORM_DATA_END()
#endif

/************************** norflash ****************************/
NORFLASH_DEV_PLATFORM_DATA_BEGIN(norflash_fat_dev_data)
    .spi_hw_num     = TCFG_FLASH_DEV_SPI_HW_NUM,
    .spi_cs_port    = TCFG_FLASH_DEV_SPI_CS_PORT,
    .spi_read_width = 4,
#if (TCFG_FLASH_DEV_SPI_HW_NUM == 1)
    .spi_pdata      = &spi1_p_data,
#elif (TCFG_FLASH_DEV_SPI_HW_NUM == 2)
    .spi_pdata      = &spi2_p_data,
#endif
    .start_addr     = 0,
    .size           = 16*1024*1024,
NORFLASH_DEV_PLATFORM_DATA_END()



/************************** otg data****************************/
#if TCFG_OTG_MODE
struct otg_dev_data otg_data = {
    .usb_dev_en = TCFG_OTG_USB_DEV_EN,
	.slave_online_cnt = TCFG_OTG_SLAVE_ONLINE_CNT,
	.slave_offline_cnt = TCFG_OTG_SLAVE_OFFLINE_CNT,
	.host_online_cnt = TCFG_OTG_HOST_ONLINE_CNT,
	.host_offline_cnt = TCFG_OTG_HOST_OFFLINE_CNT,
	.detect_mode = TCFG_OTG_MODE,
	.detect_time_interval = TCFG_OTG_DET_INTERVAL,
};
#endif

REGISTER_DEVICES(device_table) = {
#if TCFG_OTG_MODE
    { "otg",     &usb_dev_ops, (void *) &otg_data},
#endif
#if TCFG_CHARGE_ENABLE
    { "charge", &charge_dev_ops, (void *)&charge_data },
#endif

};

void debug_uart_init(const struct uart_platform_data *data)
{
#if TCFG_UART0_ENABLE
    if (data) {
        uart_init(data);
    } else {
        uart_init(&uart0_data);
    }
#endif
}

static void board_devices_init(void)
{
#if TCFG_PWMLED_ENABLE
    pwm_led_init(&pwm_led_data);
#endif

#if (TCFG_IOKEY_ENABLE || TCFG_ADKEY_ENABLE || TCFG_TOUCH_KEY_ENABLE)
	key_driver_init();
    printf("key_driver_init OK  \r\n");
#endif

#if TCFG_CHARGE_ENABLE
    charge_api_init(&charge_data);
#else
    /* CHGBG_EN(0); */
    /* CHARGE_EN(0); */
#endif

#if TCFG_RTC_ALARM_ENABLE
    alarm_init(&rtc_data);
#endif
   ;
}

//maskrom 使用到的io
static void mask_io_cfg()
{
    struct boot_soft_flag_t boot_soft_flag = {0};
    boot_soft_flag.flag0.boot_ctrl.wdt_dis = 0;
    boot_soft_flag.flag0.boot_ctrl.poweroff = 0;
    boot_soft_flag.flag0.boot_ctrl.is_port_b = JL_IOMAP->CON0 & BIT(16) ? 1 : 0;

    boot_soft_flag.flag1.misc.usbdm = SOFTFLAG_HIGH_RESISTANCE;
    boot_soft_flag.flag1.misc.usbdp = SOFTFLAG_HIGH_RESISTANCE;

    boot_soft_flag.flag1.misc.uart_key_port = 0;
    boot_soft_flag.flag1.misc.ldoin = SOFTFLAG_HIGH_RESISTANCE;

    boot_soft_flag.flag2.pa7_pb4.pa7 = SOFTFLAG_HIGH_RESISTANCE;
    boot_soft_flag.flag2.pa7_pb4.pb4 = SOFTFLAG_HIGH_RESISTANCE;

    boot_soft_flag.flag3.pc3_pc5.pc3 = SOFTFLAG_HIGH_RESISTANCE;
    boot_soft_flag.flag3.pc3_pc5.pc5 = SOFTFLAG_HIGH_RESISTANCE;
    mask_softflag_config(&boot_soft_flag);
}


extern void cfg_file_parse(u8 idx);
void board_init()
{
    P33_CON_SET(P3_PINR_CON, 0, 1, 0);//关闭长按复位功能
    VCM_DET_EN(0);//关闭VCM短按复位

	board_power_init();
	adc_vbg_init();
	adc_init();
	cfg_file_parse(0);
	devices_init();
	board_devices_init();


	if(get_charge_online_flag()) {
		power_set_mode(PWR_LDO15);
	} else {
		power_set_mode(TCFG_LOWPOWER_POWER_SEL);
	}

	/*close FAST CHARGE */
#if TCFG_UART0_ENABLE
	if (uart0_data.rx_pin < IO_MAX_NUM) {
		gpio_set_die(uart0_data.rx_pin, 1);
	}
#endif

}

enum {
    PORTA_GROUP = 0,
    PORTB_GROUP,
    PORTC_GROUP,
};

static void port_protect(u16 *port_group, u32 port_num)
{
    if (port_num == NO_CONFIG_PORT) {
        return;
    }
    port_group[port_num / IO_GROUP_NUM] &= ~BIT(port_num % IO_GROUP_NUM);
}

void usb1_iomode(u32 enable);
/*进软关机之前默认将IO口都设置成高阻状态，需要保留原来状态的请修改该函数*/
static void close_gpio(void)
{
    u16 port_group[] = {
        [PORTA_GROUP] = 0x1ff,
        [PORTB_GROUP] = 0x3ff,//
        [PORTC_GROUP] = 0x3ff,//
    };

    //port_protect(port_group, KEY1_IO);//设置按键1为 开机唤醒使用的

#if TCFG_ADKEY_ENABLE
    port_protect(port_group,TCFG_ADKEY_PORT);
#endif /* */

#if TCFG_IOKEY_ENABLE
    port_protect(port_group, TCFG_IOKEY_POWER_ONE_PORT);
    port_protect(port_group, TCFG_IOKEY_PREV_ONE_PORT);
    port_protect(port_group, TCFG_IOKEY_NEXT_ONE_PORT);
#endif /* TCFG_IOKEY_ENABLE */

#if TCFG_RTC_ALARM_ENABLE
    /* port_protect(port_group, IO_PORTA_01); */
    /* port_protect(port_group, IO_PORTA_02); */
#endif /* TCFG_RTC_ALARM_ENABLE */

    //< close gpio
    gpio_dir(GPIOA, 0, 9, port_group[PORTA_GROUP], GPIO_OR);
    gpio_set_pu(GPIOA, 0, 9, ~port_group[PORTA_GROUP], GPIO_AND);
    gpio_set_pd(GPIOA, 0, 9, ~port_group[PORTA_GROUP], GPIO_AND);
    gpio_die(GPIOA, 0, 9, ~port_group[PORTA_GROUP], GPIO_AND);
    gpio_dieh(GPIOA, 0, 9, ~port_group[PORTA_GROUP], GPIO_AND);


    gpio_dir(GPIOB, 0, 10, port_group[PORTB_GROUP], GPIO_OR);
    gpio_set_pu(GPIOB, 0, 10, ~port_group[PORTB_GROUP], GPIO_AND);
    gpio_set_pd(GPIOB, 0, 10, ~port_group[PORTB_GROUP], GPIO_AND);
    gpio_die(GPIOB, 0, 10, ~port_group[PORTB_GROUP], GPIO_AND);
    gpio_dieh(GPIOB, 0, 10, ~port_group[PORTB_GROUP], GPIO_AND);

    //< close usb io
    usb_iomode(1);
    gpio_set_pull_up(IO_PORT_DP, 0);
    gpio_set_pull_down(IO_PORT_DP, 0);
    gpio_set_direction(IO_PORT_DP, 1);
    gpio_set_die(IO_PORT_DP, 0);
    gpio_set_dieh(IO_PORT_DP, 0);

    gpio_set_pull_up(IO_PORT_DM, 0);
    gpio_set_pull_down(IO_PORT_DM, 0);
    gpio_set_direction(IO_PORT_DM, 1);
    gpio_set_die(IO_PORT_DM, 0);
    gpio_set_dieh(IO_PORT_DM, 0);

    usb1_iomode(1);
    gpio_set_pull_up(IO_PORT_DP1, 0);
    gpio_set_pull_down(IO_PORT_DP1, 0);
    gpio_set_direction(IO_PORT_DP1, 1);
    gpio_set_die(IO_PORT_DP1, 0);
    gpio_set_dieh(IO_PORT_DP1, 0);

    gpio_set_pull_up(IO_PORT_DM1, 0);
    gpio_set_pull_down(IO_PORT_DM1, 0);
    gpio_set_direction(IO_PORT_DM1, 1);
    gpio_set_die(IO_PORT_DM1, 0);
    gpio_set_dieh(IO_PORT_DM1, 0);

    /* printf("JL_USB_IO->CON0=0x%x\r\n", JL_USB_IO->CON0); */
    /* printf("JL_USB_IO->CON1=0x%x\r\n", JL_USB_IO->CON1); */
    /* printf("JL_USB->CON0=0x%x\r\n", JL_USB->CON0); */
    /*  */
    /* printf("JL_USB1_IO->CON0=0x%x\r\n", JL_USB1_IO->CON0); */
    /* printf("JL_USB1_IO->CON1=0x%x\r\n", JL_USB1_IO->CON1); */
    /* printf("JL_USB1->CON0=0x%x\r\n", JL_USB1->CON0); */
}

/************************** PWR config ****************************/
struct port_wakeup port0 = {
	.pullup_down_enable = ENABLE,                            //配置I/O 内部上下拉是否使能
	.edge               = FALLING_EDGE,                      //唤醒方式选择,可选：上升沿\下降沿
    .both_edge          = 0,

#if TCFG_ADKEY_ENABLE
	.iomap              = TCFG_ADKEY_PORT,                   //唤醒口选择
#else
	.iomap              = TCFG_IOKEY_POWER_ONE_PORT,         //唤醒口选择
#endif
    .filter             = PORT_FLT_2ms,
};

#if TCFG_TEST_BOX_ENABLE
struct port_wakeup port1 = {
    .pullup_down_enable = DISABLE,                            //配置I/O 内部上下拉是否使能
    .edge               = FALLING_EDGE,                      //唤醒方式选择,可选：上升沿\下降沿
    .both_edge          = 1,
    .filter             = PORT_FLT_1ms,
    .iomap              = TCFG_CHARGESTORE_PORT,             //唤醒口选择
};
#endif

#if TCFG_CHARGE_ENABLE
struct port_wakeup charge_port = {
    .edge               = RISING_EDGE,                       //唤醒方式选择,可选：上升沿\下降沿\双边沿
    .both_edge          = 0,
    .filter             = PORT_FLT_16ms,
    .iomap              = IO_CHGFL_DET,                      //唤醒口选择
};

struct port_wakeup vbat_port = {
    .edge               = BOTH_EDGE,                      //唤醒方式选择,可选：上升沿\下降沿\双边沿
    .both_edge          = 1,
    .filter             = PORT_FLT_16ms,
    .iomap              = IO_VBTCH_DET,                      //唤醒口选择
};

struct port_wakeup ldoin_port = {
    .edge               = BOTH_EDGE,                      //唤醒方式选择,可选：上升沿\下降沿\双边沿
    .both_edge          = 1,
    .filter             = PORT_FLT_16ms,
    .iomap              = IO_LDOIN_DET,                      //唤醒口选择
};
#endif

const struct wakeup_param wk_param = {

#if TCFG_ADKEY_ENABLE || TCFG_IOKEY_ENABLE
	.port[1]    = &port0,
#endif
	/* .sub        = &sub_wkup, */
	/* .charge     = &charge_wkup, */

#if TCFG_TEST_BOX_ENABLE
	.port[2] = &port1,
#endif
#if TCFG_CHARGE_ENABLE
    .aport[0] = &charge_port,
    .aport[1] = &vbat_port,
    .aport[2] = &ldoin_port,
#endif

};

//-----------------------------------------------

/*进软关机之前默认将IO口都设置成高阻状态，需要保留原来状态的请修改该函数*/
extern void dac_power_off(void);
void board_set_soft_poweroff(void)
{
	log_info("%s",__FUNCTION__);
	mask_io_cfg();

#if TCFG_TEST_BOX_ENABLE
	power_wakeup_index_disable(2);
#endif

	close_gpio();
}

#define     APP_IO_DEBUG_0(i,x)       //{JL_PORT##i->DIR &= ~BIT(x), JL_PORT##i->OUT &= ~BIT(x);}
#define     APP_IO_DEBUG_1(i,x)       //{JL_PORT##i->DIR &= ~BIT(x), JL_PORT##i->OUT |= BIT(x);}

void sleep_exit_callback(u32 usec)
{
	putchar('>');
    APP_IO_DEBUG_0(A, 5);
}

void sleep_enter_callback(u8  step)
{
	/* 此函数禁止添加打印 */
	if (step == 1) {
		putchar('<');
		APP_IO_DEBUG_1(A, 5);
		/*dac_power_off();*/
	} else {
		close_gpio();
	}
}

static void wl_audio_clk_on(void)
{
    JL_WL_AUD->CON0 = 1;
}

static void port_wakeup_callback(u8 index, u8 gpio)
{
	/* log_info("%s:%d,%d",__FUNCTION__,index,gpio); */

	switch (index) {
#if TCFG_TEST_BOX_ENABLE
		case 2:
			extern void chargestore_ldo5v_fall_deal(void);
			chargestore_ldo5v_fall_deal();
			break;
#endif
	}
}

static void aport_wakeup_callback(u8 index, u8 gpio, u8 edge)
{
#if TCFG_CHARGE_ENABLE
    switch (gpio) {
        case IO_CHGFL_DET://charge port
            charge_wakeup_isr();
            break;
        case IO_VBTCH_DET://vbat port
        case IO_LDOIN_DET://ldoin port
            ldoin_wakeup_isr();
            break;
    }
#endif
}

void board_power_init(void)
{
    log_info("Power init : %s", __FILE__);
    P33_CON_SET(P3_PINR_CON, 0, 1, 0);//关闭长按复位功能
    power_init(&power_param);

    //< close short key reset
    /* power_mclr(0); */
    //< close long key reset
    /* power_pin_reset(0); */

    power_set_callback(TCFG_LOWPOWER_LOWPOWER_SEL, sleep_enter_callback, sleep_exit_callback, board_set_soft_poweroff);

//    wl_audio_clk_on();

    power_keep_dacvdd_en(0);

	power_wakeup_init(&wk_param);

    aport_edge_wkup_set_callback(aport_wakeup_callback);
    port_edge_wkup_set_callback(port_wakeup_callback);

	/* #if (!TCFG_IOKEY_ENABLE && !TCFG_ADKEY_ENABLE) */
    /* charge_check_and_set_pinr(0); */
/* #endif */
}
#endif

u8 get_power_on_status(void)//获得开机状态
{
#if TCFG_IOKEY_ENABLE
    struct iokey_port *power_io_list = NULL;
    power_io_list = iokey_data.port;
    if (iokey_data.enable) {
        if (gpio_read(power_io_list->key_type.one_io.port) == power_io_list->connect_way){
            return 1;
        }
    }
#else
    //struct iokey_port *power_io_list = NULL;
    //power_io_list = iokey_data.port;
        //if(gpio_read(KEY1_IO) == 0)
        //{
            //return 1;
        //}
#endif

#if TCFG_ADKEY_ENABLE
    if (adkey_data.enable)
    {
         printf("AD KEY=%d /r/n",adc_get_value(adkey_data.ad_channel));
        if(adc_get_value(adkey_data.ad_channel) < 10)
        {
            return 1;
        }
    }
#endif
    return 0;
}

//强度加按键的检测判断使用的处理离机闪灯和无线遥控器重复接收问题
void PS_ADD_KEY_READ_2ms(void *priv)
{//KEY_ADD_Delay
    //static u8 KEY_FLAG1=0,KEY_FLAG2=0,KEY_FLAG3=0;

   // /*
    static u8 KEY_FLAG1=0;
    if(gpio_read(IO_PORT_DM)==0)//处理快速升压使用的
	{
       KEY_FLAG1++;
	}
    else
    {
       if(KEY_FLAG1>2)//表示按了按键
        {
          KEY_JM(72);//快速升压测试使用的
        }
       KEY_FLAG1=0;
    }
   // */

    if(BT24G_Clear_Delays!=0)
    {
        BT24G_Clear_Delays--;
        if(BT24G_Clear_Delays==0)
        {
          rx_bufferLS[0]=0x50;
          rx_bufferLS[1]=0x50;
        }
    }

    if(SYS_Flag==2)//控制离机后LED闪烁使用的
    {
       LED_Delay_500S++;
       EMS_LJ_Delay_120S++;
       if(LED_Delay_500S==400)
       {
         LED_OFF();
       }
       else if(LED_Delay_500S>800)
       {
         LED_ON();
         LED_Delay_500S=0;
       }

       if(EMS_LJ_Delay_120S>60000)
       {
           SYS_Flag=0;
           log_info(">>>LJ 2M SYS OFF\n");
           Buzzer_ON(2);//开启蜂鸣器
       }
    }
    else
    {
      LED_Delay_500S=0;
      EMS_LJ_Delay_120S=0;
    }

}

//LED状态的显示，充电状态，充满电状态
void LED_Show_500ms(void *priv)
{
  u16 LS_VBAT;
  //printf("LED_Show_500ms .SYS_Flag=%d Ci=%d /r/n",SYS_Flag,LED_Show_Ci);
    if(SYS_Init_OK_Flag==1)//排除开机按键对按键的影响了
    {
      if(get_power_on_status()==0)//判断按键没有按下
      {
        SYS_Init_OK_Flag=0;
      }
    }

  if(SYS_Flag==4)//充电状态
  {
     VBAT_CD_Full_Delay20S=0;
     FD_OFF();//开放电
     LED_Show_Ci++;
     if(LED_Show_Ci>2)//灭0.5秒，开1秒
     {
         LED_Show_Ci=0;
          LED_OFF();
     }
     else
     {
         LED_ON();
     }
     //if(LED_Show_Ci>5) LED_Show_Ci=0;
  }
  else if(SYS_Flag==5)//充满电状态
  {
     //LED_8_Data=LED_CD_DataX[6];//显示一个F
     LED_ON();
     FD_OFF();//开放电
     VBAT_CD_Full_Delay20S++;
     if(VBAT_CD_Full_Delay20S>40)//直接关机进入低功耗
     {
        SYS_Flag=0;
        LED_OFF();
        power_set_soft_poweroff();//关机进入超低功耗
     }
  }
  else if((SYS_Flag==1)||(SYS_Flag==2))//电池电量低检测使用的
  {
        LS_VBAT=get_vbat_level();//获得电池电压
        //printf("VBAT_V=%d /r/n",VBAT_V);
        if(LS_VBAT<320)//低电量提醒 322
        {
          VBAT_V+=LS_VBAT;
          if(VBAT_V>1280)//低压连续检测出4次后才判断为低压需要进入低压提示功能
          {
            SYS_Flag=3;//低电量提醒功能
            EMS_ALL_OFF();//关闭EMS
            FD_ON();//开放电
            sys_hi_timer_add(NULL, EMS_FD_500ms_TO_OFF, 500);//开启放电功能
            Buzzer_ON(6);//开启蜂鸣器
          }
        }
        else
        {
          VBAT_V=0;
        }
        //开机定时15分钟后关机
        LED_SHOW_TIMER_DELAY_500MS++;
        if(LED_SHOW_TIMER_DELAY_500MS>=120)
        {
           LED_SHOW_TIMER_DELAY_500MS=0;
           // /* //临时屏蔽15分钟定时关机功能
           if(LED_SHOW_TIMER_DATA>0)
           {
             LED_SHOW_TIMER_DATA--;
             if(LED_SHOW_TIMER_DATA==0)
             {
               SYS_to_LED_OFF_Init();//定时时间到了直接关机
             }
           }// */
        }

        if(LED_SHOW_TIMER_DATA==15)//计时是从00:15:00开始
        {
           if(LED_SHOW_TIMER_DELAY_500MS>=2)
           {
             LED_SHOW_TIMER_DATA=14;
           }
        }
  }
}

//开机运行15分钟后自动关机
void SYS_ON_TO_OFF_15Ms(void *priv)
{
     // 已经作废不用了  /* //屏蔽15分钟定时关机功能
      printf("SYS_15MSYS_Close OK..ID=%d/r/n",SYS_ON_TO_OFF_15Ms_ID);
       if(SYS_ON_TO_OFF_15Ms_ID!=0)
       {
          if((SYS_Flag==1)||(SYS_Flag==2))//正常开机的情况下和离机的情况下有效
          {
             SYS_to_LED_OFF_Init();
          }
       }
       SYS_ON_TO_OFF_15Ms_ID=0; //*/
}


//控制蜂鸣器用的PWM驱动
void buzzer_pwm_out_init(void)
{
  struct pwm_platform_data pwm_p_data;
  pwm_p_data.pwm_aligned_mode = pwm_edge_aligned;         //边沿对齐
  pwm_p_data.pwm_ch_num = pwm_ch1;                        //通道号
  pwm_p_data.frequency = 4000;                            //20KHz 最大只能40全开了
  pwm_p_data.duty = 5000;                                 //占空比20% 0-10000
  pwm_p_data.h_pin = IO_PORTA_02;                         //任意引脚
  pwm_p_data.l_pin = -1;                                  //任意引脚,不需要就填-1
  pwm_p_data.complementary_en = 0;                        //两个引脚的波形, 0: 同步,  1: 互补，互补波形的占空比体现在H引脚上
  mcpwm_init(&pwm_p_data);
  Buzzer_PWM_OFF();
}

//系统开机的初始化
void SYS_to_LED_ON_Init(void)
{
    u8 LSSNDATA[4];
    SYS_Flag=1;
    VBAT_V=0;
    SYS_Init_OK_Flag=1;
    EMS_OUT_TO_100HZ_FLAG=0;//开启
    EMS_OUT_TO_100HZ_Ci=0;
    LED_SHOW_TIMER_DELAY_500MS=0;
    LED_SHOW_TIMER_DATA=15;

    P33_CON_SET(P3_PINR_CON, 0, 1, 0);//关闭长按复位功能
    VCM_DET_EN(0);//关闭VCM短按复位
    log_info(">>>SYS ON\n");

    //放电的驱动
    gpio_set_die(FD_PORT_IO, 1);//设置为数字引脚
    gpio_set_direction(FD_PORT_IO, 0);//设置为输出模式
    gpio_set_pull_down(FD_PORT_IO, 0);//下拉关
    gpio_set_pull_up(FD_PORT_IO, 0);//上拉关
    FD_ON();//开启放电

    buzzer_pwm_out_init();//蜂鸣器初始化

    //led的灯脚初始化
     gpio_set_die(LED_PORT_IO, 1);//设置为数字引脚
     gpio_set_direction(LED_PORT_IO, 0);//设置为输出模式
     gpio_set_pull_down(LED_PORT_IO, 0);//下拉关
     gpio_set_pull_up(LED_PORT_IO, 0);//上拉关
     LED_ON();

     //SP1的驱动
     gpio_set_die(SP1_PORT_IO, 1);//设置为数字引脚
     gpio_set_direction(SP1_PORT_IO, 0);//设置为输出模式
     gpio_set_pull_down(SP1_PORT_IO, 0);//下拉关
     gpio_set_pull_up(SP1_PORT_IO, 0);//上拉关
     SP1_OFF();

     //SP11的驱动
     usb_iomode(1);//开启转换为IO模式
     gpio_set_die(SP11_PORT_IO, 1);//设置为数字引脚
     gpio_set_direction(SP11_PORT_IO, 0);//设置为输出模式
     gpio_set_pull_down(SP11_PORT_IO, 0);//下拉关
     gpio_set_pull_up(SP11_PORT_IO, 0);//上拉关
     SP11_OFF();

     //SP2的驱动
     gpio_set_die(SP2_PORT_IO, 1);//设置为数字引脚
     gpio_set_direction(SP2_PORT_IO, 0);//设置为输出模式
     gpio_set_pull_down(SP2_PORT_IO, 0);//下拉关
     gpio_set_pull_up(SP2_PORT_IO, 0);//上拉关
     SP2_OFF();

     //SP22的驱动
     gpio_set_die(SP22_PORT_IO, 1);//设置为数字引脚
     gpio_set_direction(SP22_PORT_IO, 0);//设置为输出模式
     gpio_set_pull_down(SP22_PORT_IO, 0);//下拉关
     gpio_set_pull_up(SP22_PORT_IO, 0);//上拉关
     SP22_OFF();

     ///*
     usb_iomode(1);//开启转换为IO模式
     gpio_set_die(IO_PORT_DM, 1);//设置为数字引脚1数字 0模拟
     gpio_set_direction(IO_PORT_DM, 1);//设置为输入模式 0输出，1输入
     gpio_set_pull_up(IO_PORT_DM, 1);//上拉开
     gpio_set_pull_down(IO_PORT_DM, 0);//下拉关
     //*/

     //离机的初始化
     gpio_set_die(LJ_PD_IO, 1);//设置为数字引脚
     gpio_set_direction(LJ_PD_IO, 1);//设置为输入模式
     gpio_set_pull_down(LJ_PD_IO, 0);//下拉关
     gpio_set_pull_up(LJ_PD_IO, 0);//上拉关

     LED_2ms_ID=0;
     //SYSINI_FLAG=0;
     //HVCC_AD_IO_INIT();//HVCC的电压获得

     sys_hi_timer_add(NULL, PS_ADD_KEY_READ_2ms, 2);//改造为每隔2ms检测一次按键状态，用来判断强度按键是否被按下
     //SYS_ON_TO_OFF_15Ms_ID=sys_hi_timer_add(NULL, SYS_ON_TO_OFF_15Ms, 1000*60*15);//开启LED强度数显扫描功能
     FD_OFF();
     EMS_TEMS_Init();//EMS的初始化
     printf("SYS_to_LED_ON_Init OK.....\r\n");
     LED_2ms_ID=sys_hi_timer_add(NULL, LED_Show_500ms, 500);//0.5秒监测一次，监测充电和电池电量低检测了 15分钟关机也在这里处理
     Buzzer_ON(1);//蜂鸣器开启响1声
     u16 LINS=0;
     //遥控器密码的读取
     LINS= syscfg_read(CFG_USER_DEFINE_24GSN, SYS_24G_SN_BYTE, 4);
     if(LINS==0)
     {
       SYS_24G_SN_BYTE[0]=0;
       SYS_24G_SN_BYTE[1]=0;
       SYS_24G_SN_BYTE[2]=0;
       SYS_24G_SN_BYTE[3]=0;
     }
     printf("SYS_to_LED_ON_Init OK1..%d.. SN1=%d,SN2=%d,SN3=%d,SN4=%d, /r/n",LINS,SYS_24G_SN_BYTE[0],SYS_24G_SN_BYTE[1],SYS_24G_SN_BYTE[2],SYS_24G_SN_BYTE[3]);
     /*
     SYS_24G_SN_BYTE[0]=0xA2;
     SYS_24G_SN_BYTE[1]=0x78;
     SYS_24G_SN_BYTE[2]=0x0F;
     SYS_24G_SN_BYTE[3]=0x35;
     syscfg_write(CFG_USER_DEFINE_24GSN, SYS_24G_SN_BYTE, 4);
     LINS= syscfg_read(CFG_USER_DEFINE_24GSN, SYS_24G_SN_BYTE, 4);
     if(LINS==0)
     {
       SYS_24G_SN_BYTE[0]=0;
       SYS_24G_SN_BYTE[1]=0;
       SYS_24G_SN_BYTE[2]=0;
       SYS_24G_SN_BYTE[3]=0;
     }
     printf("SYS_to_LED_ON_Init OK2..%d.. SN1=%d,SN2=%d,SN3=%d,SN4=%d, /r/n",LINS,SYS_24G_SN_BYTE[0],SYS_24G_SN_BYTE[1],SYS_24G_SN_BYTE[2],SYS_24G_SN_BYTE[3]);
     */
}

//系统关机的初始化
void SYS_to_LED_OFF_Init(void)
{
  SYS_Flag=0;
  EMS_ALL_OFF();//关闭EMS
  FD_ON();//开放电
  LED_OFF();//关闭LED
  sys_hi_timer_add(NULL, EMS_FD_500ms_TO_OFF, 500);//开启放电功能
  log_info(">>>SYS OFF\n");
  Buzzer_ON(2);//开启蜂鸣器
}
